package com.chenfan.process.entity.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.chenfan.ccp.entity.BaseEntity;
import com.chenfan.ccp.plug.mybatis.annotation.Column;
import com.chenfan.infra.context.UserContextHolder;
import com.chenfan.infra.vo.UserVO;
import com.chenfan.process.common.constants.ProcessConstants;
import com.chenfan.process.entity.vo.ProcessDetailVo;
import com.chenfan.process.enums.ProcessResultTypeEnums;
import lombok.*;
import org.springframework.beans.BeanUtils;

import java.util.Date;
import java.util.Objects;

/**
 * @author K
 * @date 2021/3/5
 */
@EqualsAndHashCode(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@TableName(value = "chenfan_paas_process_detail_po")
public class ProcessDetailPo extends BaseEntity<ProcessDetailPo> {

    public static final String RESULT_TYPE = "result_type";
    public static final String PARENT_ID = "parent_id";
    public static final String PROCESS_ID = "process_id";
    public static final String APPROVAL_TEMPLATE_ID = "approval_template_id";

    /**
     * 参考 {@link com.chenfan.process.enums.ProcessResultTypeEnums}
     */
    @Column(commit = "过程的状态,参考 {@link com.chenfan.process.enums.ProcessResultType}", length = 4)
    private Integer resultType;

    @Column(commit = "执行的任务的Id")
    private Long processId;

    @Column(commit = "下一个任务节点Id")
    private Long nextProcessId;

    @Column(commit = "组id")
    private Long groupId;

    @Column(commit = "审批模板ID")
    private Long approvalTemplateId;
    @Column(commit = "审批ID", defaultVal = "0")
    private Long parentId;
    @Column(commit = "是否是多样,false不是，true是 默认值 不是", length = 1, defaultVal = "false")
    private Boolean multiple;
    @Column(commit = "意见")
    private String remark;
    @Column(commit = "创建人")
    private Long createBy;
    @Column(commit = "创建人名称")
    private String createName;
    @Column(commit = "更新人")
    private Long updateBy;
    @Column(commit = "更新人名称")
    private String updateName;
    @Column(commit = "最后节点的表示", length = 1, defaultVal = "false")
    private Boolean finishFlag;

    public ProcessDetailVo copyProcessDetailVo() {
        ProcessDetailVo vo = new ProcessDetailVo();
        org.springframework.beans.BeanUtils.copyProperties(this, vo);
        return vo;
    }

    public void update() {
        setUpdateTime(new Date());
        UserVO userVo = UserContextHolder.getUserVo();
        if (Objects.nonNull(userVo)) {
            setUpdateBy(userVo.getUserId());
            setUpdateName(userVo.getRealName());
        }
    }

    public ProcessDetailPo updateSelf() {
        setUpdateTime(new Date());
        return this;
    }

    public ProcessDetailPo cloneProcessDetailPo() {
        ProcessDetailPo processDetailPo = new ProcessDetailPo();
        BeanUtils.copyProperties(this, processDetailPo);
        processDetailPo.setResultType(ProcessResultTypeEnums.CREATED.getIndex());
        processDetailPo.setCreateTime(new Date());
        processDetailPo.setUpdateBy(null);
        processDetailPo.setUpdateName(null);
        processDetailPo.setRemark(null);
        return processDetailPo;
    }

    public boolean isSharedApproval() {
        return Objects.equals(ProcessConstants.OR_SIGN_NODE, nextProcessId);
    }

    public boolean isCounterSign() {
        return ProcessConstants.COUNTER_SIGN_NODE.equals(nextProcessId);
    }

    public boolean isSpecialNode() {
        return ProcessConstants.COUNTER_SIGN_NODE.equals(nextProcessId)
            || ProcessConstants.OR_SIGN_NODE.equals(nextProcessId);
    }

    public void refuse() {
        setResultType(ProcessResultTypeEnums.REFUSED.getIndex());
        update();
    }

    public void revoke() {
        setResultType(ProcessResultTypeEnums.REVOKE.getIndex());
        update();
    }

    public void reject(String remark) {
        setResultType(ProcessResultTypeEnums.REJECTED.getIndex());
        setRemark(remark);
        update();
    }

    public void agree(String remark) {
        setResultType(ProcessResultTypeEnums.PASS.getIndex());
        setRemark(remark);
        update();
    }

    public void pass() {
        setResultType(ProcessResultTypeEnums.PASS.getIndex());
        update();
    }

    public void skippedPaas() {
        agree("系统自动执行, 原因: 与历史节点审批人相同");
    }
}
